package main;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

import scenario.*;
 
public class UI extends Applet
{
	public static final long serialVersionUID = 0;

	public Game game;
	public final MoveMouse moveMouse = new MoveMouse();
	public final ShootMouse shootMouse = new ShootMouse();
	public final FightMouse fightMouse = new FightMouse();
	public final MyKey myKey = new MyKey();
	
	public static Random rng = new Random();
	
	public boolean drawingLine = false;
	public int rootX = 0;
	public int rootY = 0;
	public int destX = 0;
	public int destY = 0;
	
	public int boardOffsetX = 0;
	public int boardOffsetY = 0;
	
	public Panel statsPanel;
	
	public Graphics bufferG;
	public Image offscreen;
	public Dimension dim;
	
	public static String message = "";
	
	public void init()
	{
		game = new AmbushTutorial();
		
		Game.myUI = this;
		Unit.myUI = this;
		Battle.myUI = this;
		MyMouse.myUI = this;
		MyMouse.game = game;

		MyKey.myUI = this;
		//game.setupTest();
		
		setLayout(null);
		dim = getSize();
		offscreen = createImage(dim.width, dim.height);
		bufferG = offscreen.getGraphics();
		
		UnitSelecter u = new UnitSelecter(this);
		
		repaint();
	}
	
	public void beginGame() {
		Button endPhase = new Button("End Phase");
		endPhase.setName("End Phase");
		endPhase.setBounds(dim.width-100,0,100,50);

		final Label phaseLabel = new Label(game.currPhase + ": " + game.currArmy);
		phaseLabel.setBounds(dim.width/2-50,0,100,30);
		phaseLabel.setAlignment(Label.CENTER);
		
		
		endPhase.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				game.endPhase();
				phaseLabel.setText(game.currPhase + ": " + game.currArmy);
			}
		});
		
		add(endPhase);
		add(phaseLabel);
		statsPanel = buildStatsPanel("Selected Unit", dim.width-100, dim.height-250);
		statsPanel.setName("statsPanel");
		add(statsPanel);
		this.addMouseListener(moveMouse);
		this.addMouseMotionListener(moveMouse);
		this.addKeyListener(myKey);
		
		System.out.println(this.getKeyListeners().length);
		repaint();
	}
	
	
	public void openMoveUI() {
	}
	public void closeMoveUI() {
	}
	
	public void openShootUI() {
		game.shootTarget = null;
		Button shoot = new Button("Shoot");
		shoot.setName("Shoot");
		shoot.setBounds(dim.width-100,50,100,50);
		shoot.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				game.selectedUnit.shootAt(game.shootTarget);
			}
		});
		Panel shootStats = buildStatsPanel("Target", dim.width-200, dim.height-250);
		shootStats.setName("Shoot Stats");
		add(shootStats);
		add(shoot);
		revalidate();
		repaint();
	}
	public void closeShootUI() {
		this.removeByName("Shoot");
		this.removeByName("Shoot Stats");
		this.game.shootTarget = null;
		revalidate();
		repaint();
	}
	
	public void openFightUI() {
		Button fight = new Button("Fight Battle");
		fight.setName("Fight");
		fight.setBounds(dim.width-100,50,100,50);
		fight.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (game.selectedUnit != null && game.selectedUnit.battle != null)
					game.selectedUnit.battle.resolve();
			}
		});
		add(fight);
	}
	public void closeFightUI() {
		this.removeByName("Fight");
	}
	
	public void removeByName(String name) {
		for (int i = 0; i < this.getComponentCount(); i++) {
			if (this.getComponent(i).getName().equals(name)) {
				this.remove(i);
				i--;
			}
		}
	}
	public Component getByName(String name) {
		for (int i = 0; i < this.getComponentCount(); i++) {
			if (this.getComponent(i).getName().equals(name)) {
				return this.getComponent(i);
			}
		}
		return null;
	}
	
	public Panel buildStatsPanel(String title, int x, int y) {
		Panel p = new Panel();
		Label t = new Label(title);
		Label moveLeft = new Label("Move Left: N/A");
		Label str = new Label("Strength: N/A");
		Label def = new Label("Defense: N/A");
		Label att = new Label("Attacks: N/A");
		Label wou = new Label("Wounds: N/A");
		Label cou = new Label("Courage: N/A");
		Label fv = new Label("FightValue: N/A");
		Label sv = new Label("ShootValue: N/A");
		
		p.setBounds(x, y, 100, 250);
		p.add(t);
		p.add(moveLeft);
		p.add(str);
		p.add(def);
		p.add(att);
		p.add(wou);
		p.add(cou);
		p.add(fv);
		p.add(sv);
		return p;
	}
	public void updateStatsPanel() {
		if (game.selectedUnit != null) {
			((Label)statsPanel.getComponent(1)).setText("Move Left: " + String.format("%.2f", game.selectedUnit.moveLeft));
			((Label)statsPanel.getComponent(2)).setText("Strength: " + game.selectedUnit.strength);
			((Label)statsPanel.getComponent(3)).setText("Defense: " + game.selectedUnit.defense);
			((Label)statsPanel.getComponent(4)).setText("Attacks: " + game.selectedUnit.attacks);
			((Label)statsPanel.getComponent(5)).setText("Wounds: " + game.selectedUnit.wounds);
			((Label)statsPanel.getComponent(6)).setText("Courage: " + game.selectedUnit.courage);
			((Label)statsPanel.getComponent(7)).setText("FightValue: " + game.selectedUnit.fightValue);
			((Label)statsPanel.getComponent(8)).setText("ShootValue: " + game.selectedUnit.shootValue);
		}
		else {
			((Label)statsPanel.getComponent(1)).setText("Move Left: -");
			((Label)statsPanel.getComponent(2)).setText("Strength: -");
			((Label)statsPanel.getComponent(3)).setText("Defense: -");
			((Label)statsPanel.getComponent(4)).setText("Attacks: -");
			((Label)statsPanel.getComponent(5)).setText("Wounds: -");
			((Label)statsPanel.getComponent(6)).setText("Courage: -");
			((Label)statsPanel.getComponent(7)).setText("FightValue: -");
			((Label)statsPanel.getComponent(8)).setText("ShootValue: -");
		
		}
	
	}
	public void updateTargetPanel() {
		if (game.shootTarget != null) {
			Panel p = (Panel)this.getByName("Shoot Stats");
			((Label)p.getComponent(1)).setText("Move Left: " + String.format("%.2f", game.shootTarget.moveLeft));
			((Label)p.getComponent(2)).setText("Strength: " + game.shootTarget.strength);
			((Label)p.getComponent(3)).setText("Defense: " + game.shootTarget.defense);
			((Label)p.getComponent(4)).setText("Attacks: " + game.shootTarget.attacks);
			((Label)p.getComponent(5)).setText("Wounds: " + game.shootTarget.wounds);
			((Label)p.getComponent(6)).setText("Courage: " + game.shootTarget.courage);
			((Label)p.getComponent(7)).setText("FightValue: " + game.shootTarget.fightValue);
			((Label)p.getComponent(8)).setText("ShootValue: " + game.shootTarget.shootValue);
		}
	}
	
	public void paint (Graphics g)
    {
		// draw things to bufferG
		this.requestFocus();
		
		if (game.armies[0] == null) {
			g.drawImage(offscreen, 0, 0, this);
			offscreen = createImage(dim.width, dim.height);
			bufferG = offscreen.getGraphics();
			return;
		}
		
		if (game.board.background != null) {
			bufferG.drawImage(game.board.background, -1*boardOffsetX, -1*boardOffsetY, null);
		}
		
		// Draw units
    	for(Army a : game.armies) {
    		for (Unit u : a.units) {
        		bufferG.drawOval(u.x-15-boardOffsetX, u.y-15-boardOffsetY, 30, 30);
        		bufferG.drawString(u.name + "-" + u.id, u.x-boardOffsetX, u.y-boardOffsetY);
        		bufferG.drawString(u.equipmentString(), u.x-boardOffsetX, u.y+10-boardOffsetY);
    		}
    	}
    	
    	// Selected Unit stuff
    	if (game.selectedUnit != null && game.selectedUnit.wounds > 0){
    		bufferG.drawOval(game.selectedUnit.x-16-boardOffsetX, game.selectedUnit.y-16-boardOffsetY, 32, 32);
    		if (game.selectedUnit.battle != null) {
    			bufferG.drawString(game.selectedUnit.battle.toString(), 150, dim.height-30);
    		}
    	}
		updateStatsPanel();
    	if (game.shootTarget != null){
    		bufferG.setColor(Color.red);
    		bufferG.drawOval(game.shootTarget.x-16-boardOffsetX, game.shootTarget.y-16-boardOffsetY, 32, 32);
    		bufferG.setColor(Color.black);
    	}
		updateTargetPanel();
		
    	
		// Draw message
		bufferG.drawString(message, 0, dim.height - 50);
    	
    	// Draw move line
    	if (drawingLine) {
    		bufferG.drawLine(rootX-boardOffsetX, rootY-boardOffsetY, destX-boardOffsetX, destY-boardOffsetY);
    		bufferG.drawString(String.format("%.2f", Utils.inchDist(rootX, rootY, destX, destY)), destX-boardOffsetX, destY-boardOffsetY);
    	}
		
		g.drawImage(offscreen, 0, 0, this);
		offscreen = createImage(dim.width, dim.height);
		bufferG = offscreen.getGraphics();
    }
	
	public void update(Graphics g) 
    {
    	paint(g);
    }
}